using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace url2jpegCtn
{
    public partial class navigator : UserControl
    {
        public int m_width, m_height, m_widthOffset, m_heightOffset;
        private bool m_bScrollBarsEnabled = true;
        private bool m_bAutoResize = false;

        public delegate void PageLoadedHandler(string url);
        public event PageLoadedHandler PageLoadedEvent;
        public delegate void NavigationCompleteHandler();
        public event NavigationCompleteHandler NavigationCompleteEvent;
        public delegate void NewWindowHandler(string url);
        public event NewWindowHandler NewWindowEvent;
        public delegate void BeforeNavigateHandler(string url);
        public event BeforeNavigateHandler BeforeNavigateEvent;

        public class Element : TreeNode
        {
            public Rectangle m_position;

            public Element(HtmlElement element, Rectangle pos)
            {
                string result = element.TagName + " " + element.Style;
                if (element.InnerText != null)
                {
                    if (element.InnerText.Length < 20)
                        result += " - " + element.InnerText;
                    else
                        result += " - " + element.InnerText.Substring(0, 20) + "...";
                }
                Text = result;
                m_position = pos;
            }
        }

        public navigator()
        {
            InitializeComponent();
            browser.ScriptErrorsSuppressed = true;
        }

        public void Navigate(string url)
        {
            timerAutoResize.Enabled = false;
            timerDocLoaded.Enabled = false;
            browser.ScrollBarsEnabled = m_bScrollBarsEnabled;
            browser.Size = new Size(Width, Height);
            browser.Navigate(url);
        }

        public void Stop()
        {
            browser.Stop();
        }

        private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (PageLoadedEvent != null && e != null)
                PageLoadedEvent(e.Url.ToString());

            if (browser.Document != null && browser.Document.Body != null)
            {
                if (m_bAutoResize)
                {
                    m_width = browser.Document.Body.ScrollRectangle.Width + m_widthOffset;
                    m_height = browser.Document.Body.ScrollRectangle.Height + m_heightOffset;
                }
                else
                {
                    m_width = this.Width;
                    m_height = this.Height;
                }
                browser.Size = new Size(m_width, m_height);
            }

            if (!browser.IsBusy && NavigationCompleteEvent != null)
                NavigationCompleteEvent();

            if (e != null)
                Console.WriteLine(System.DateTime.Now.ToLongTimeString() + " " + e.Url.ToString());
        }

        public void ScrollBarsEnabled(bool val)
        {
            m_bScrollBarsEnabled = val;
            browser.ScrollBarsEnabled = val;
        }

        public void AutoResize(bool val, int widthOffset, int heightOffset)
        {
            m_bAutoResize = val;
            m_widthOffset = widthOffset;
            m_heightOffset = heightOffset;
            browser_DocumentCompleted(null, null);
        }

        private void timerDocLoaded_Tick(object sender, EventArgs e)
        {
            timerDocLoaded.Enabled = false;
            if (!m_bScrollBarsEnabled)
                browser.ScrollBarsEnabled = false;
        }

        private void browser_BeforeNewWindow(object sender, pixtek.browser.BrowserExtendedNavigatingEventArgs e)
        {
            e.Cancel = true;
            if (NewWindowEvent != null)
                NewWindowEvent(e.Url);
        }

        private void browser_BeforeNavigate(object sender, pixtek.browser.BrowserExtendedNavigatingEventArgs e)
        {
            if (BeforeNavigateEvent != null)
                BeforeNavigateEvent(e.Url);
        }

        private void navigator_SizeChanged(object sender, EventArgs e)
        {
            timerAutoResize.Enabled = false;
            timerAutoResize.Enabled = true;
        }

        private void timerAutoResize_Tick(object sender, EventArgs e)
        {
            timerAutoResize.Enabled = false;
            browser_DocumentCompleted(null, null);
        }

        [DllImport("uCapture.dll")]
        static extern IntPtr CreateBitmap2(IntPtr IDispatch, int x, int y);

        [DllImport("gdi32.dll")]
        static extern bool DeleteObject(IntPtr hObject);

        public Bitmap CaptureBitmap()
        {
            IntPtr hBitmap = CreateBitmap2(Marshal.GetIDispatchForObject(browser.ActiveXInstance), m_width, m_height);
            Bitmap bmp = Bitmap.FromHbitmap(hBitmap);
            DeleteObject(hBitmap);
            return bmp;
        }

        public void FillTreeView(TreeView tv)
        {
            tv.Nodes.Clear();
            if (browser.Document != null)
            {
                FillTreeNode(tv.Nodes.Add("body"), browser.Document.Body);
            }
        }

        private void FillTreeNode(TreeNode tn, HtmlElement root)
        {
            HtmlElementCollection col = root.Children;
            foreach (HtmlElement element in col)
            {
                HtmlElement elem = element;
                int dx = 0, dy = 0;
                while (elem != null)
                {
                    dx += elem.OffsetRectangle.Left;
                    dy += elem.OffsetRectangle.Top;
                    elem = elem.OffsetParent;
                }
                Rectangle tmpRect = new Rectangle(dx, dy, element.OffsetRectangle.Width, element.OffsetRectangle.Height);
                Element node = new Element(element, tmpRect);
                // Element node = new Element(element, element.ClientRectangle);
                // Console.WriteLine("{0} - {1} - {2} - {3} - {4}", element.TagName+element.Style, parentRect, tmpRect, element.OffsetRectangle, element.OffsetParent.OffsetRectangle);
                tn.Nodes.Add(node);
                FillTreeNode(node, element);
            }
        }
    }
}

